#pragma once
#include "exmesh.h"

class ExPortal;

class ExHullMesh :
	public ExMesh
{
public:
	
	ExHullMesh(void);
	virtual ~ExHullMesh(void);

	virtual bool Save( TiXmlNode* pContentSection );

private:

	int _FindPlane( const Common::Plane& peq );
	bool _IsPortal( uint32 materialIndex );

	//used for search index on the convex hull
	struct BiIndex
	{
		BiIndex();
		BiIndex(uint32 i1, uint32 i2);

		uint32& operator[](uint32 index);
		const uint32& operator[](uint32& index);

		uint32 i1;
		uint32 i2;
	};

	struct TriIndex
	{
		TriIndex();
		TriIndex(uint32 i1, uint32 i2, uint32 i3);

		uint32& operator[](uint32 index);
		const uint32& operator[](uint32& index);

		uint32 i1;
		uint32 i2;
		uint32 i3;
	};


	bool _MakeConvex( BVVector& vertices, std::vector<TriIndex>& faces ) const;
	void _ExtractPlanesAndPortals( BVVector& vertices, std::vector<TriIndex>& faces );
	Triangle*	_FindOriginalTriangle( TriIndex& face );
	
	//ultility functions
	bool	mcCreateMaxTetrahedron	(	const BVVector& vertices, std::vector<uint32>& verts,
										std::vector<TriIndex>& faces, const float epsilon = 0.0001f ) const;

	void	mcRemoveVertex(const uint32 vertIndex, const BVVector& srcVertices, std::vector<uint32>& modVerts, const float epsilon = 0.0001f ) const;

	bool	mcRemoveInsideVertices	(	const BVVector& vertices, std::vector<uint32>& verts,
										const std::vector<TriIndex>& faces ) const;
	uint32	mcFindNextFurthestVertToHull(	const BVVector& vertices, const std::vector<uint32>& verts,
										const std::vector<TriIndex>& faces ) const;
	void	mcExpandHull			(	const uint32 vertIndex, const BVVector& vertices,
										std::vector<uint32>& verts, std::vector<TriIndex>& faces ) const;
	bool	mcIsInternalEdge		(	std::vector<TriIndex>& faces, const std::vector<uint32>& frontFacing,
										const uint32 vertIndex1, const uint32 vertIndex2) const;
	void	mcAddFaces				(	const uint32 vertIndex, const std::vector<uint32>& horizonVerts,
										std::vector<TriIndex>& faces ) const;

private:
	
	typedef std::vector<Common::Plane> Boundaries;
	Boundaries	m_conPlanes;
	
	typedef std::map<int,ExPortal*> PortalMap;
	PortalMap m_conPortals;
};

